package com.qian.ddj.pay.util.YLUtils;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;

/**
 * json工具类
 * @author chenzf
 * @date 2016年9月11日
 */

public class JsonUtils {
	public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";

	/**
	 * 创建基本gson
	 * @param names
	 * @return  gson对象
	 */
	public static Gson createGson(final String... names) {
		ExclusionStrategy exclusionStrategy = new ExclusionStrategy() {

			@Override
			public boolean shouldSkipField(FieldAttributes fa) {
				if (ArrayUtils.isEmpty(names)) {
					return false;
				}
				for (String name : names) {
					if (fa.getName().equals(name)) {
						return true;
					}
				}
				return false;
			}

			@Override
			public boolean shouldSkipClass(Class<?> arg0) {
				return false;
			}
		};

		return build(DEFAULT_DATE_PATTERN, exclusionStrategy).create();
	}

	/**
	 * 将json数据转化成map对象
	 * @param json json字符串
	 * @return Map<String, String>
	 */
	public static Map<String, String> toMap(String json) {
		return createGson().fromJson(json, new TypeToken<Map<String, String>>() {
		}.getType());
	}

	/**
	 * 将对象转换成json字符串
	 * @param object
	 * @return
	 */
	public static String toJson(Object object) {
		return createGson().toJson(object);
	}

	/**
	 * 将对象转换成json格式map
	 * @param object
	 * @return
	 */
	public static Map<String, String> toJsonMap(Object object) {
		return toMap(toJson(object));
	}

	/**
	 * 格式化字段名成json数据 <br>
	 * someFieldName ---> some_field_name
	 * @param object
	 * @return
	 */
	public static String formatFiledName(Object object) {
		return build(true).create().toJson(object);
	}

	/**
	 * 格式化字段名并转换成对象<br>
	 * someFieldName ---> some_field_name
	 * @param <T>
	 * @param object
	 * @return
	 */
	public static <T> T parseFiledName(String json, Class<T> clazz) throws Exception {
		T newInstance = clazz.newInstance();
		Gson gson = build(true).create();
		if (newInstance instanceof List || newInstance instanceof Map) {
			return gson.fromJson(json, new TypeToken<T>() {
			}.getType());
		}
		return gson.fromJson(json, clazz);
	}

	/**
	 * 格式化Map字段名并转换成对象<br>
	 * some_field_name ---> someFieldName
	 * @param map
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public static <T, K, V> T parseFiledName(Map<K, V> map, Class<T> clazz) throws Exception {
		return parseFiledName(toJson(map), clazz);
	}

	/**
	 * 将对象的字段名格式化并转换成map
	 * @param object 
	 * @return
	 */
	public static Map<String, String> formatFiledtoMap(Object object) {
		return toMap(formatFiledName(object));
	}

	private static GsonBuilder build(boolean isFormat) {
		return build(isFormat, null);
	}

	public static GsonBuilder build(String dateFormat, ExclusionStrategy... exclusionStrategy) {
		return build(false, dateFormat, exclusionStrategy);
	}

	public static GsonBuilder build(boolean isFormat, String dateFormat, ExclusionStrategy... exclusionStrategy) {
		return build(isFormat, true, dateFormat, exclusionStrategy);
	}

	private static GsonBuilder build(boolean isFormat, boolean isLongToString, String dateFormat,
			ExclusionStrategy... exclusionStrategy) {
		GsonBuilder gsonBuilder = new GsonBuilder();
		if (isFormat) {
			gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
		}
		if (isLongToString) {
			gsonBuilder.setLongSerializationPolicy(LongSerializationPolicy.STRING);
		}
		if (StringUtils.isNotBlank(dateFormat)) {
			gsonBuilder.setDateFormat(dateFormat);
		}
		if (exclusionStrategy != null) {
			gsonBuilder.setExclusionStrategies(exclusionStrategy);
		}
		return gsonBuilder;
	}
}
